package org.useCode.redis;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;


public class DateUtils {

	/**
	 * 根据基础时间(base),单位(unit),偏移量(differ)对时间进行偏移并返回偏移后的时间
	 * @param base
	 * @param forward
	 * @param unit
	 * @param differ
	 * @return
	 */
	public static Date shiftDate(Date base, boolean forward, DateUnit unit, int differ){
		if(base == null){
			return null;
		}
		if(differ <= 0){
			return base;
		}
		
		Calendar c = Calendar.getInstance();
		c.setTime(base);
		
		c.set(unit.getUnit(), c.get(unit.getUnit()) +(forward ? differ : -differ));
		
		return c.getTime();
	}
	
	public enum DateUnit{
		
		YEAR(Calendar.YEAR),
		MONTH(Calendar.MONTH),
		WEEK(Calendar.MONTH),
		DAY(Calendar.DAY_OF_YEAR),
		HOUR(Calendar.HOUR_OF_DAY),
		MINUE(Calendar.MINUTE),
		SECOND(Calendar.SECOND);
		
		private int unit;
		
		private DateUnit(int unit){
			this.unit = unit;
		}

		public int getUnit() {
			return unit;
		}

		public void setUnit(int unit) {
			this.unit = unit;
		}
		
	}
	

	/**
	 * 获取一天开始的时间点，如： 2015-05-22 11:49:13， 返回 2015-05-22 00:00:00
	 * @param date
	 * @return
	 */
	public static Date getStartOfDate(Date date){
		if(date == null){
			return null;
		}
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		
		return cal.getTime();
	}
	
	/**
	 * 获取一天开始的时间点，如： 2015-05-22 11:49:13， 返回 2015-05-22 00:00:00
	 * @param dateStr 字符串日期
	 * @param format  日期格式
	 * @return
	 */
	public static Date getStartOfDate(String dateStr, String format){
		return getStartOfDate(parseDate(dateStr, format));
	}
	
	/**
	 * 获取一天的结束时间点， 如： 2015-05-22 11:49:13， 返回 2015-05-22 23:59:59
	 * @param date
	 * @return
	 */
	public static Date getEndOfDate(Date date){
		if(date == null){
			return null;
		}
		
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		
		cal.set(Calendar.HOUR_OF_DAY, 23);
		cal.set(Calendar.MINUTE, 59);
		cal.set(Calendar.SECOND, 59);
		cal.set(Calendar.MILLISECOND, 999);
		
		return cal.getTime();
	}
	
	/**
	 * 获取一天的结束时间点， 如： 2015-05-22 11:49:13， 返回 2015-05-22 23:59:59
	 * @param dateStr 字符串日期
	 * @param format  日期格式
	 * @return
	 */
	public static Date getEndOfDate(String dateStr, String format){
		return getEndOfDate(parseDate(dateStr, format));
	}
	
	/**
	 * 格式化日期
	 * @param dateStr
	 * @param format
	 * @return
	 */
	public static Date parseDate(String dateStr, String format){
		DateFormat formatter = new SimpleDateFormat(format);
		if(dateStr == null || "".equals(dateStr.trim())){
			return null;
		}
		
		try {
			return formatter.parse(dateStr.trim());
		} catch (ParseException e) {}
		
		return null;
	}
	
	public static String formatDate(Date date, String format){
		if(date == null){
			return null;
		}
		DateFormat formatter = new SimpleDateFormat(format);
		return formatter.format(date);
	}
	
	/**
	 * 默认以 <code>yyyy-MM-dd HH:mm:ss</code>格式化日期
	 * @param date
	 * @return
	 */
	public static String format(Date date){
		return formatDate(date,"yyyy-MM-dd HH:mm:ss");
	}
	
	/**
	 * 
	 * 获取参数日期所在的周一的日期 
	 * 
	 * @return
	 */
	public static Date getMondayOFWeek(Date date){
    	int mondayPlus = getMondayPlus(date);
    	
    	Calendar ca = Calendar.getInstance();
    	ca.setTime(date);
    	ca.add(GregorianCalendar.DATE, mondayPlus);
    	
    	Date monday = ca.getTime();
    	
    	return monday;
    }
	/**
	 * 获取一周的星期日，此接口返回的星期日的逻辑为中国自然周，即周一~周日
	 * @param date
	 * @return
	 */
	public static Date getSundayOfWeek(Date date){
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		boolean isSunday = c.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY;
		if(!isSunday){
			c.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
			c.add(Calendar.DAY_OF_YEAR, 7);
		}
		return DateUtils.getEndOfDate(c.getTime());
	}
    
	// 获得当前日期与本周一相差的天数
    private static int getMondayPlus(Date date) {
    	Calendar ca = Calendar.getInstance();
    	ca.setTime(date);
    	
	    int dayOfWeek = ca.get(Calendar.DAY_OF_WEEK)-1; //一星期的第一天是周一；不是周天
	    int result = 0;
	    if(dayOfWeek == 0){
	    	result = -6;
	    }else if(dayOfWeek == 1){
	    	result = 0;
	    }else{
	    	result = 1-dayOfWeek;
	    }
	    return result;
    }
    
    
    public static String getStanderDateTimeStr(Date date){
    	if(date == null){
    		return null;
    	}
    	
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    	return sdf.format(date);
    }
    
    public static long getDistanceByMin(Date start,Date end){
		long startMills = start.getTime();
		long endMills = end.getTime();
		long distance = Math.abs((endMills -  startMills));
		long result = distance/(1000*60);
		return result;
	}

	public static long getDistanceByHour(Date start,Date end){
		long distanceByMin = getDistanceByMin(start, end);
		return distanceByMin / 60;
	}
    
    /**
     * 解析HHmm格式的时间
     * @param strOfHHmm
     * @return
     */
    public static Date getDateOnlyHHmm(String strOfHHmm){
    	Date date = null;
    	try {
    		date = new SimpleDateFormat("HH:mm").parse(strOfHHmm);
		} catch (ParseException e) {
		}
    	return date;
    }
    
    /**
     * 将时间对象转换为yyyy-MM-dd格式的字符串
     * @param strOfHHmm
     * @return
     */
    public static String getDateStr(Date date){
    	if(date == null){
    		return null;
    	}
    	String dateStr = null;
    	try {
    		dateStr = new SimpleDateFormat("yyyy-MM-dd").format(date);
		} catch (Exception e) {
		}
    	return dateStr;
    }
    
    /**
	 * 判断当前日期再加上天数后是否和指定的日期是否是同一天
	 * @param addDays
	 * @param targetDate
	 * @return true:是同一天;false:不是同一天
	 */
	public static boolean equalTargetDate(Date currentDate,int addDays,Date targetDate){
		String dateFormate = "yyyy-MM-dd";
		Calendar nowCa = Calendar.getInstance();
		nowCa.setTime(currentDate);
		
		nowCa.add(Calendar.DATE, addDays);
		String newDateStr = DateUtils.formatDate(nowCa.getTime(),dateFormate);
		String targetDateStr = DateUtils.formatDate(targetDate,dateFormate);
		return newDateStr.equals(targetDateStr);
	}
	
    public static boolean isBetween(Date date , Date minDate,Date maxDate){
    	if(minDate == null || maxDate == null || date == null){
    		return false;
    	}
    	
    	long dateLong = date.getTime();
    	if(dateLong >= minDate.getTime() && dateLong <= maxDate.getTime()){
    		return true;
    	}
    	return false;
    }
    
    /**
     * 将毫秒转换为时分秒
     * 
     * @param ms
     * @return
     */
    public static String msToTime(long ms){
    	// 转换为秒
    	long second = ms / 1000;
    	// 转换小时
        long hours = second / 3600;
        // 剩余秒数
        second = second % 3600;
        // 转换分钟
        long minutes = second / 60;  
        // 剩余秒数
        second = second % 60;
        
        return hours + "小时" + minutes + "分" + second + "秒";
    }
    
    public static void main(String[] args) {
    	Date start = DateUtils.parseDate("2016-04-11 17:55", "yyyy-MM-dd HH:mm");
    	Date end = DateUtils.parseDate("2016-04-11 14:00", "yyyy-MM-dd HH:mm");
    	long  ms = 300001 * 1000 ;
    	System.out.println(msToTime(ms));
    	long distance = getDistanceByMin(start, end);
    	System.out.println(distance);
		System.out.println(getDistanceByHour(end, start));
	}
    
}
